package cn.com.fssg.platform.base.handler.impl.pjqc;

import cn.com.fssg.platform.base.handler.InterfaceHandler;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 评价期次预统分和统分评级
 */
@Component
public class PjqcCount implements InterfaceHandler {

//    private NamedParameterJdbcTemplate jdbcTemplate = BizUtil.cur().tenantMainJdbcTemplate();

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public Object run(HttpServletRequest request, JSONObject jsonObject) throws Exception {
        // 评价期次id
        String qcid = jsonObject.get("qcid").toString();
        // 是否预统分，是的话预统分，否的话就是统分评级
        Boolean isPre = jsonObject.getBoolean("isPre");
        String sql = "SELECT * FROM bs_pjqc WHERE id=:qcid ";
        // 先查询  期次是统计人员还是企业
        HashMap<String, Object> params = new HashMap<>();
        params.put("qcid", qcid);
        List<Map<String, Object>> queryForList = jdbcTemplate.queryForList(sql, params);
        List<Map<String, Object>> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(queryForList)) {
            return result;
        }
        Map<String, Object> pjqc = queryForList.get(0);
        // 评价类别，人员还是企业
        String pjlb = (String) pjqc.get("pjlb");
        // 评价类别对应企业类型或者人员类型
        String pjff = (String) pjqc.get("pjff");
        // 评价开始和结束时间
        Date pjkssj = (Date) pjqc.get("pjkssj");
        Date pjjssj = (Date) pjqc.get("pjjssj");
        params.put("pjkssj", DateUtil.format(pjkssj, "yyyy-MM-dd HH:mm:ss"));
        params.put("pjjssj", DateUtil.format(pjjssj, "yyyy-MM-dd HH:mm:ss"));
        params.put("pjff", pjff);
        if ("人员".equals(pjlb)) {
            sql = "SELECT DISTINCT ON (dj.id) dj.*, xw.lxmc,qy.qymc,ry.xm,p.bdhtje FROM bs_ryxyxwdj dj LEFT JOIN bs_zcpjdy p ON dj.bdid = p.ID LEFT JOIN bs_qyryxx ry ON dj.qyryid=ry.id  LEFT JOIN bs_qyjbxx qy ON dj.qyid=qy.id LEFT JOIN bs_xwlx xw ON dj.xwlxid = xw.id  " +
                    "LEFT JOIN bs_gjrysb sb ON dj.bdid=sb.bdid AND dj.qyryid=sb.qyryid WHERE dj.sfzp='0' AND dj.bdid not IN (SELECT bcp.bdid FROM bs_pjqc_bcpbd bcp WHERE bcp.parentid=:qcid )" +
                    " AND sb.rylx=:pjff and dj.fsrq between :pjkssj and :pjjssj";
            if (!isPre) {
                sql += "AND dj.zt =:zt";
                params.put("zt", "终审通过");
            }
            List<Map<String, Object>> ryxyxwList = jdbcTemplate.queryForList(sql, params);
            if (!CollectionUtils.isEmpty((ryxyxwList))) {
                // 根据人员id分组
                Map<Object, List<Map<String, Object>>> qyryCollect = ryxyxwList.parallelStream().collect(Collectors.groupingBy(ry -> ry.get("qyryid")));
                for (Map.Entry<Object, List<Map<String, Object>>> ryEntry : qyryCollect.entrySet()) {
                    // 再按标段进行分组
                    Map<Object, List<Map<String, Object>>> bdCollect = ryEntry.getValue().stream().collect(Collectors.groupingBy(xw -> xw.get("bdid")));
                    // 记录得分
                    double fm = 0; //信用评价得分（Y）分母
                    double fz = 0; //信用评价得分（Y) 分子
                    double xwzf = 0; //履约行为评价总分
                    double khzf = 0; //专项考核总分
                    for (Map.Entry<Object, List<Map<String, Object>>> bdEntry : bdCollect.entrySet()) {
                        double bdxwzf = 100; // 初始化总分100
                        double bdkhzf = 70; // 初始化总分70
                        // 遍历进行履约行为得分计算
                        bdxwzf -= bdEntry.getValue().stream().filter(xw -> "履约行为".equals(xw.get("lxmc")))
                                .map(xw -> xw.get("fs"))
                                .filter(Objects::nonNull)
                                .mapToDouble(fs -> (Double) fs)
                                .sum();
//                        for (Map<String, Object> xw : bdEntry.getValue()) {
//                            Object fs = xw.get("fs");
//                            if (fs != null) {
//                                // 进行履约行为得分计算
//                                bdxwzf = (bdxwzf - (Double) fs);
//                            }
//                        }
                        xwzf += bdxwzf; //累加每个标段的行为得分
                        khzf += bdkhzf; //累加每个标段的考核得分
                        double bdhtje = ((BigDecimal) bdEntry.getValue().get(0).get("bdhtje")).doubleValue(); // 标段合同金额
                        fz += (bdxwzf * 0.3 + bdkhzf) * bdhtje;
                        fm += bdhtje;
                    }
                    // 返回的记录行
                    Map<String, Object> ryxyxwItem = ryEntry.getValue().get(0);
                    Map<String, Object> ryRecord = new HashMap<>();
                    // 人员id
                    ryRecord.put("ryid", ryxyxwItem.get("qyryid"));
                    // 人员姓名
                    ryRecord.put("ryxm", ryxyxwItem.get("xm"));
                    // 企业id
                    ryRecord.put("qyid", ryxyxwItem.get("qyid"));
                    // 企业名称
                    ryRecord.put("qymc", ryxyxwItem.get("qymc"));
                    // 评价期次id
                    ryRecord.put("qcid", qcid);
                    // 行为得分 所有标段得分平均数
                    ryRecord.put("xwdf", xwzf / bdCollect.size());
                    // 考核得分 所有标段得分平均数
                    ryRecord.put("khdf", khzf / bdCollect.size());
                    // 最后总得分
                    double fs = fz / fm;
                    // 保留小数点两位
                    ryRecord.put("fs", String.format("%.2f", fs));
                    // 信用等级
                    ryRecord.put("xydj", getXydj(fs));
                    result.add(ryRecord);
                }
            }


        } else {
            sql = "SELECT DISTINCT ON (dj.id) dj.*, xw.lxmc,qy.zzjgdm,qy.qymc,(select count(x.id) from bs_xmzcxx x left join bs_xzzbbh h on x.id=h.parentid left join bs_xzbdfl l on h.id=l.parentid where l.id=p.parentid) as xms, " +
                    "p.bdhtje FROM bs_qyxyxwdj dj left join bs_zcpjdy p on p.id=dj.bdid LEFT JOIN bs_qyjbxx qy ON dj.qyid=qy.id LEFT JOIN bs_xwlx xw ON dj.xwlxid = xw.id  WHERE dj.sfzp='0' " +
                    "AND dj.bdid not IN (SELECT bcp.bdid FROM bs_pjqc_bcpbd bcp WHERE bcp.parentid=:qcid ) AND qy.qylx=:pjff and dj.fsrq between :pjkssj and :pjjssj";

            if (!isPre) {
                sql += "AND dj.zt =:zt";
                params.put("zt", "终审通过");
            }
            List<Map<String, Object>> qyxyxwList = jdbcTemplate.queryForList(sql, params);
            if (!CollectionUtils.isEmpty(qyxyxwList)) {
                // 根据企业id分组
                Map<Object, List<Map<String, Object>>> qyCollect = qyxyxwList.parallelStream().collect(Collectors.groupingBy(ry -> ry.get("qyid")));
                for (Map.Entry<Object, List<Map<String, Object>>> qyEntry : qyCollect.entrySet()) {
                    // 投标行为总分
                    double T = 0;
                    // 履约行为总分
                    double L = 0;
                    // 其他行为扣分
                    double J = 0;
                    // 再按行为类型分组
                    Map<String, List<Map<String, Object>>> xwCollect = qyEntry.getValue().stream().collect(Collectors.groupingBy(xw -> (String) xw.get("lxmc")));
                    for (Map.Entry<String, List<Map<String, Object>>> xwEntry : xwCollect.entrySet()) {
                        // 投标行为，履约行为或其他行为
                        String xwlx = xwEntry.getKey();
                        if ("投标行为".equals(xwlx)) {
                            // 进行投标行为得分计算
                            T = 100 - xwEntry.getValue().stream().map(xw -> xw.get("fs"))
                                    .filter(Objects::nonNull)
                                    .mapToDouble(fs -> (Double) fs)
                                    .sum();
                            T = T > 100 ? 100 : T;
                        } else if ("履约行为".equals(xwlx)) {
                            double fm = 0; // 分母
                            double fz = 0; // 分子
                            // 按标段进行分组,统计累加
                            Map<String, Double> bdCollect = xwEntry.getValue().stream()
                                    .collect(Collectors.groupingBy(xw -> (String) xw.get("bdid"),
                                            Collectors.summingDouble(xw -> Double.parseDouble(xw.get("fs") == null ? "0" : xw.get("fs").toString()))));
                            // 企业类别
                            if ("设计企业".equals(pjff)) {
                                // 按标段进行分组,收集每个标段对应的合同金额
                                Map<String, Double> htjeCollect = xwEntry.getValue().stream()
                                        .collect(Collectors.groupingBy(
                                                xw -> (String) xw.get("bdid"),
                                                Collectors.collectingAndThen(
                                                        Collectors.toList(),
                                                        list -> ((BigDecimal) list.get(0).get("bdhtje")).doubleValue()
                                                )
                                        ));
                                for (Map.Entry<String, Double> bdEntry : bdCollect.entrySet()) {
                                    // 计算每个标段履约行为得分 100-扣分
                                    double df = 100 - bdEntry.getValue();
                                    fz += (df > 100 ? 100 : df) * htjeCollect.get(bdEntry.getKey());
                                    fm += htjeCollect.get(bdEntry.getKey());
                                }
                            } else {
                                //施工企业和监理企业类型
                                // 进行排序
                                List<Map.Entry<String, Double>> entryList = bdCollect.entrySet().stream()
                                        .sorted(Map.Entry.comparingByValue())
                                        .collect(Collectors.toList());

                                for (int i = 0; i < entryList.size(); i++) {
                                    fm += (i + 1);
                                    // 计算每个标段履约行为得分 100-扣分
                                    double df = 100 - entryList.get(i).getValue();
                                    fz += (i + 1) * (df > 100 ? 100 : df);
                                }
                            }
                            // 最终履约行为得分
                            L = fz / fm;
                        } else {
                            // 其他扣分或者加分行为
                            J = xwEntry.getValue().stream().map(xw -> xw.get("fs")).filter(Objects::nonNull)
                                    .mapToDouble(fs -> (Double) fs)
                                    .sum();

                        }
                    }
                    // 进行合同金额统计，每个标段合同金额累加
                    // 直接计算去重后的bdhtje总和
                    double total = qyEntry.getValue().stream()
                            .collect(Collectors.groupingBy(
                                    xw -> (String) xw.get("bdid"),
                                    Collectors.collectingAndThen(
                                            Collectors.toList(),
                                            list -> ((BigDecimal) list.get(0).get("bdhtje")).doubleValue()
                                    )
                            ))
                            .values()
                            .stream()
                            .mapToDouble(Double::doubleValue)
                            .sum();
                    // 返回的记录行
                    Map<String, Object> qyxyxwItem = qyEntry.getValue().get(0);
                    Map<String, Object> ryRecord = new HashMap<>();
                    // 企业id
                    ryRecord.put("qyid", qyxyxwItem.get("qyid"));
                    // 企业名称
                    ryRecord.put("qymc", qyxyxwItem.get("qymc"));
                    // 企业组织机构代码
                    ryRecord.put("zzjgdm", qyxyxwItem.get("zzjgdm"));
                    // 项目数
                    ryRecord.put("xms", qyxyxwItem.get("xms"));
                    // 评价期次id
                    ryRecord.put("qcid", qcid);
                    // 投标行为得分
                    ryRecord.put("tbxwdf", T);
                    // 履约行为得分
                    ryRecord.put("lyxwdf", L);
                    // 其他行为得分
                    ryRecord.put("qtxwkf", J);
                    // 合同金额
                    ryRecord.put("htze", total);
                    // 最后总得分
                    double fs;
                    if (T == 0 && L != 0) {
                        // 只存在履约行为
                        fs = L - J;
                    } else if (T != 0 && L == 0) {
                        // 只存在投标行为
                        fs = T - J;
                    } else {
                        // 存在履约行为和投标行为
                        fs = 0.1 * T + 0.9 * L - J;
                    }
                    ryRecord.put("fs", String.format("%.2f", fs));
                    // 信用等级
                    ryRecord.put("xydj", getXydj(fs));
                    // 项目类型
                    ryRecord.put("xmlx", "公路工程");
                    result.add(ryRecord);
                }

            }

        }

        return result;
    }

    /**
     * 获取信用等级
     * @param fs 分数
     * @return 信用等级
     */
    private String getXydj(double fs) {
        if (fs >= 95) {
            return "AA";
        } else if (fs >= 85) {
            return "A";
        } else if (fs >= 75) {
            return "B";
        } else if (fs >= 60) {
            return "C";
        } else {
            return "D";
        }
    }

}
